﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Windows.Forms;
using AnimaGestionPersonnage.Properties;
using AnimaGestionPersonnage.Vue;

namespace AnimaGestionPersonnage.Utilities
{
    /// <summary>
    /// Classe qui regroupe des fonctions globale ainsi que des variables
    /// utiles a l'ensemble du système
    /// </summary>
    public static class Utils
    {
        public static FormChoice topForm = new FormChoice();
        private static int currentState;
        public static int tpCombat = 0,
                            tpMystic = 0,
                            tpPsychic = 0;
        // le personnage sur lequel on "travail"
        public static Character charac = new Character(DEFAULT_CREATION, DEFAULT_DISADVANTAGE);
        // Listes des données(base de données)
        public static List<BasicSkill> basicSkillsList = new List<BasicSkill>();
        public static List<PrimarySkill> primarySkillsList = new List<PrimarySkill>();
        public static List<SecondarySkill> secondarySkillsList = new List<SecondarySkill>();
        public static List<Race> racesList = new List<Race>();
        public static List<CharacterClass> classList = new List<CharacterClass>();
        public static List<AdvDisadv> advDisadvList = new List<AdvDisadv>();
        public static List<CombatModule> combatModuleList = new List<CombatModule>();
        public static List<TypicalModule> weaponModuleList = new List<TypicalModule>();
        public static List<Weapon> weaponList = new List<Weapon>();
        public static List<MartialArts> martialArtsList = new List<MartialArts>();

        #region CONSTANT
        public const int LOAD_STATE = 1,
                            NEW_STATE = 2,
                            LOADING_STATE = 10,
                            OPEN_STATE = 100,
                            DEFAULT_STATE = 0,
                            ADVANTAGE = 3,
                            DISADVANTAGE = 4,
                            INNATE_BONUS = 30,
                            REDUCED_COST = 40,
                            RACE_BONUS = 50,
                            DEFAULT_CREATION = 3,
                            DEFAULT_DISADVANTAGE = 3,
                            ERROR = -1;
        public const String LP_MULTI = "Multiplicateur de vie",
                            ATTACK = "Attaque",
                            BLOCK = "Parade",
                            DODGE = "Esquive",
                            WEAR_ARMOR = "Port d'armure",
                            ACC_KI = "Acc",
                            KI = "Ki",
                            ZEON = "Zeon",
                            MA_MULTIP = "Accumulation d'AMR",
                            MAGIC_PRO = "Projection magique",
                            SUMMON = "Convoquer",
                            CONTROL = "Dominer",
                            BIND = "Lier",
                            BANISH = "Révoquer",
                            PPP = "PPP",
                            PSY_PRO = "Projection psychique",
                            MAGIC_LEVEL = "Niveau de Magie",
                            MARTIAL_KNOWLEDGE = "Développement Intérieur",
                            MARTIAL_LIMIT = "martialLimit",
                            MYSTIC_LIMIT = "mysticLimit",
                            PSY_LIMIT = "psyLimit",
                            ATHLETIC = "Athlétiques",
                            VIGOR = "Vitales",
                            PERCEPTION = "Sensorielles",
                            INTELECTUAL = "Intellectuelles",
                            SOCIAL = "Sociales",
                            SUBTERFUGE = "Cladestines",
                            CREATIVE = "Créatives";

        #endregion

        #region Getter Info by association

        public static int getCurrentState()
        {
            return currentState;
        }

        public static void setCurrentState(int newState)
        {
            currentState = newState;
        }

        #region Getter info for Character

        /// <summary>
        /// verifie le perso peu avoir des couts pour les skills et si il a une arme principale selectionner
        /// </summary>
        /// <returns>retourne vrai si les donnees sont bonnes</returns>
        public static bool isCharacValidForSkill()
        {
            bool tempVal = false;

            if (charac.charClass != null && charac.principalWeapon != null)
            {
                tempVal = true;
            }

            return tempVal;
        }

        public static int getSkillCost(BasicSkill skill)
        {
            int tempCost = -1;
            Boolean notFound = true;

            if (skill.name.Equals(MARTIAL_KNOWLEDGE) || skill.name.Equals(MAGIC_LEVEL))
            {
                tempCost = 1;
            }
            else
            {
                foreach (CharacterClass cc in classList)
                {
                    if (cc.Equals(charac.charClass))
                    {
                        int tempIndex = classList.IndexOf(cc);
                        foreach (SkillMod kvp in classList[tempIndex].reducedCosts)
                        {
                            if (kvp.Equals(skill.name))
                            {
                                tempCost = kvp.value;
                                notFound = false;
                            }
                        }
                        if (notFound)
                        {
                            foreach (SkillMod kvp in classList[tempIndex].normalCosts)
                            {
                                if (kvp.Equals(skill.name))
                                {
                                    tempCost = kvp.value;
                                    notFound = false;
                                }
                            }
                        }
                        if (notFound)
                        {
                            string tempStr;
                            switch (skill.type)
                            {
                                case TypeSkill.Athlétiques:
                                    tempStr = ATHLETIC;
                                    break;
                                case TypeSkill.Cladestines:
                                    tempStr = SUBTERFUGE;
                                    break;
                                case TypeSkill.Créatives:
                                    tempStr = CREATIVE;
                                    break;
                                case TypeSkill.Intellectuelles:
                                    tempStr = INTELECTUAL;
                                    break;
                                case TypeSkill.Sensorielles:
                                    tempStr = PERCEPTION;
                                    break;
                                case TypeSkill.Sociales:
                                    tempStr = SOCIAL;
                                    break;
                                case TypeSkill.Vitales:
                                    tempStr = VIGOR;
                                    break;
                                default:
                                    tempStr = "ERROR";
                                    break;
                            }
                            foreach (SkillMod kvp in classList[tempIndex].normalCosts)
                            {
                                if (kvp.Equals(tempStr))
                                {
                                    tempCost = kvp.value;
                                    notFound = false;
                                }
                            }
                        }
                        if (notFound)
                        {
                            if (skill.name.Substring(0, 3).Equals(ACC_KI))
                            {
                                foreach (SkillMod kvp in classList[tempIndex].normalCosts)
                                {
                                    if (kvp.Equals(skill.name.Substring(0, 3)))
                                    {
                                        tempCost = kvp.value;
                                        notFound = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return tempCost;
        }

        #region int getStatBonus(Stats/Skill)

        public static int getStatBonus(Stats stat)
        {
            int tempVal;
            switch (stat)
            {
                case Stats.Agilité:
                    tempVal = getStatBonusValue(charac.agi);
                    break;
                case Stats.Constitution:
                    tempVal = getStatBonusValue(charac.con);
                    break;
                case Stats.Dextérité:
                    tempVal = getStatBonusValue(charac.dex);
                    break;
                case Stats.Force:
                    tempVal = getStatBonusValue(charac.str);
                    break;
                case Stats.Inteligence:
                    tempVal = getStatBonusValue(charac.intel);
                    break;
                case Stats.Perception:
                    tempVal = getStatBonusValue(charac.per);
                    break;
                case Stats.Pouvoir:
                    tempVal = getStatBonusValue(charac.pow);
                    break;
                case Stats.Volonté:
                    tempVal = getStatBonusValue(charac.will);
                    break;
                default:
                    tempVal = -100;
                    break;
            }
            return tempVal;
        }

        public static int getStatBonus(PrimarySkill skill)
        {
            int tempBonus = getStatBonus(skill.stat);

            if (skill.name.Substring(0, 3).Equals(ACC_KI))
            {
                tempBonus = getAccKi(skill.stat);
            }

            return tempBonus;
        }

        public static int getStatBonus(BasicSkill skill)
        {
            int tempVal;
            switch (skill.name)
            {
                case LP_MULTI:
                    tempVal = getBaseLifePoint();
                    break;
                case ZEON:
                    tempVal = getZeon();
                    break;
                case MA_MULTIP:
                    tempVal = getMABase();
                    break;
                case MARTIAL_KNOWLEDGE:
                case MAGIC_LEVEL:
                case PPP:
                    tempVal = 0;
                    break;
                case KI:
                    tempVal = getPointOfKi(charac.pow) + getPointOfKi(charac.will) + getPointOfKi(charac.con)
                                 + getPointOfKi(charac.dex) + getPointOfKi(charac.agi) + getPointOfKi(charac.str);
                    break;
                default:
                    tempVal = -100;
                    break;
            }
            return tempVal;
        }

        #endregion

        private static int getAccKi(Stats stat)
        {
            int tempAcc,
                tempVal;

            switch (stat)
            {
                case Stats.Agilité:
                    tempVal = charac.agi;
                    break;
                case Stats.Constitution:
                    tempVal = charac.con;
                    break;
                case Stats.Dextérité:
                    tempVal = charac.dex;
                    break;
                case Stats.Force:
                    tempVal = charac.str;
                    break;
                case Stats.Inteligence:
                    tempVal = charac.intel;
                    break;
                case Stats.Perception:
                    tempVal = charac.per;
                    break;
                case Stats.Pouvoir:
                    tempVal = charac.pow;
                    break;
                case Stats.Volonté:
                    tempVal = charac.will;
                    break;
                default:
                    tempVal = -100;
                    break;
            }

            if (tempVal < 1)
                tempAcc = -100;
            else if (tempVal < 10)
                tempAcc = 1;
            else if (tempVal < 13)
                tempAcc = 2;
            else if (tempVal < 16)
                tempAcc = 3;
            else if (tempVal < 21)
                tempAcc = 4;
            else
                tempAcc = -100;

            return tempAcc;
        }

        public static int getPointOfKi(int stat)
        {
            int tempKi;

            if (stat <= 10)
            {
                tempKi = stat;
            }
            else if (stat <= 20)
            {
                tempKi = 10 + ((stat - 10) * 2);
            }
            else
            {
                tempKi = -100;
            }

            return tempKi;
        }

        public static int getBaseLifePoint()
        {
            int tempLP = -100;

            switch (charac.con)
            {
                case 1:
                    tempLP = 5;
                    break;
                case 2:
                    tempLP = 20;
                    break;
                case 3:
                    tempLP = 40;
                    break;
                case 4:
                    tempLP = 55;
                    break;
                case 5:
                    tempLP = 70;
                    break;
                case 6:
                    tempLP = 85;
                    break;
                case 7:
                    tempLP = 95;
                    break;
                case 8:
                    tempLP = 110;
                    break;
                case 9:
                    tempLP = 120;
                    break;
                case 10:
                    tempLP = 135;
                    break;
                case 11:
                    tempLP = 150;
                    break;
                case 12:
                    tempLP = 160;
                    break;
                case 13:
                    tempLP = 175;
                    break;
                case 14:
                    tempLP = 185;
                    break;
                case 15:
                    tempLP = 200;
                    break;
                case 16:
                    tempLP = 215;
                    break;
                case 17:
                    tempLP = 225;
                    break;
                case 18:
                    tempLP = 240;
                    break;
                case 19:
                    tempLP = 250;
                    break;
                case 20:
                    tempLP = 265;
                    break;
            }

            return tempLP;
        }

        public static int getZeon()
        {
            int tempZeon = -100;

            switch (charac.pow)
            {
                case 1:
                    tempZeon = 5;
                    break;
                case 2:
                    tempZeon = 20;
                    break;
                case 3:
                    tempZeon = 40;
                    break;
                case 4:
                    tempZeon = 55;
                    break;
                case 5:
                    tempZeon = 70;
                    break;
                case 6:
                    tempZeon = 85;
                    break;
                case 7:
                    tempZeon = 95;
                    break;
                case 8:
                    tempZeon = 110;
                    break;
                case 9:
                    tempZeon = 120;
                    break;
                case 10:
                    tempZeon = 135;
                    break;
                case 11:
                    tempZeon = 150;
                    break;
                case 12:
                    tempZeon = 160;
                    break;
                case 13:
                    tempZeon = 175;
                    break;
                case 14:
                    tempZeon = 185;
                    break;
                case 15:
                    tempZeon = 200;
                    break;
                case 16:
                    tempZeon = 215;
                    break;
                case 17:
                    tempZeon = 225;
                    break;
                case 18:
                    tempZeon = 240;
                    break;
                case 19:
                    tempZeon = 250;
                    break;
                case 20:
                    tempZeon = 265;
                    break;
            }

            return tempZeon;
        }

        public static int getMABase()
        {
            int tempMABase;
            switch (charac.pow)
            {
                case 1:
                case 2:
                case 3:
                case 4:
                    tempMABase = 0;
                    break;
                case 5:
                case 6:
                case 7:
                    tempMABase = 5;
                    break;
                case 8:
                case 9:
                case 10:
                case 11:
                    tempMABase = 10;
                    break;
                case 12:
                case 13:
                case 14:
                    tempMABase = 15;
                    break;
                case 15:
                    tempMABase = 20;
                    break;
                case 16:
                case 17:
                    tempMABase = 25;
                    break;
                case 18:
                case 19:
                    tempMABase = 30;
                    break;
                case 20:
                    tempMABase = 35;
                    break;
                default:
                    tempMABase = -100;
                    break;
            }

            return tempMABase;
        }

        private static int getStatBonusValue(int statVal)
        {
            int tempVal;

            switch (statVal)
            {
                case 1:
                    tempVal = -30;
                    break;
                case 2:
                    tempVal = -20;
                    break;
                case 3:
                    tempVal = -10;
                    break;
                case 4:
                    tempVal = -5;
                    break;
                case 5:
                    tempVal = 0;
                    break;
                case 6:
                case 7:
                    tempVal = 5;
                    break;
                case 8:
                case 9:
                    tempVal = 10;
                    break;
                case 10:
                    tempVal = 15;
                    break;
                case 11:
                case 12:
                    tempVal = 20;
                    break;
                case 13:
                case 14:
                    tempVal = 25;
                    break;
                case 15:
                    tempVal = 30;
                    break;
                case 16:
                case 17:
                    tempVal = 35;
                    break;
                case 18:
                case 19:
                    tempVal = 40;
                    break;
                case 20:
                    tempVal = 45;
                    break;
                default:
                    tempVal = 100;
                    break;
            }

            return tempVal;
        }

        #region  int getTotal(Skill)

        public static int getTotal(SecondarySkill skill)
        {
            return getStatBonus(skill.stat) + getNatBonus(skill) + (skill.tP / getSkillCost(skill)) + getLevelBonus(skill) + getOtherBonuses(skill) + skill.otherBonus;
        }

        public static int getTotal(PrimarySkill skill)
        {
            return getStatBonus(skill) + (skill.tP / getSkillCost(skill)) + getLevelBonus(skill) + getOtherBonuses(skill) + skill.otherBonus;
        }

        public static int getTotal(BasicSkill skill)
        {
            int tempTotal = getStatBonus(skill) + getLevelBonus(skill) + getOtherBonuses(skill) + skill.otherBonus; ;

            switch (skill.name)
            {
                case LP_MULTI:
                    tempTotal += ((skill.tP / getSkillCost(skill)) * charac.con);
                    break;
                case MA_MULTIP:
                    tempTotal = ((skill.tP / getSkillCost(skill)) + 1) * getStatBonus(skill);
                    break;
                case ZEON:
                    tempTotal += ((skill.tP / getSkillCost(skill)) * 5);
                    break;
                default:
                    tempTotal += (skill.tP / getSkillCost(skill));
                    break;
            }


            return tempTotal;
        }

        #endregion

        private static int getOtherBonuses(BasicSkill skill)
        {
            int tempValue = 0;

            foreach (AdvDisadv adv in charac.advantage)
            {
                foreach (SkillMod sm in adv.modToSkill)
                {
                    if (sm.Equals(skill.name))
                    {
                        tempValue = sm.value;
                    }
                }
            }
            foreach (AdvDisadv dis in charac.disadvantage)
            {
                foreach (SkillMod sm in dis.modToSkill)
                {
                    if (sm.Equals(skill.name))
                    {
                        tempValue = sm.value;
                    }
                }
            }
            return tempValue;
        }

        public static int getNatBonus(SecondarySkill skill)
        {
            return getStatBonus(skill.stat) * skill.naturalBonus;
        }

        public static int getLevelBonus(BasicSkill skill)
        {
            int tempLvlBonus;

            tempLvlBonus = getBonusPerLevel(skill) * getLevel();

            if (tempLvlBonus < 0)
                tempLvlBonus = 0;
            else if (tempLvlBonus > 50 && (skill.Equals(ATTACK) || skill.Equals(BLOCK) || skill.Equals(DODGE)))
                tempLvlBonus = 50;

            return tempLvlBonus;
        }

        public static int getBonusPerLevel(BasicSkill skill)
        {
            int tempValue = 0;
            CharacterClass tempClass = getCharacterClass(charac.charClass);

            if (skill.name.Equals(MARTIAL_KNOWLEDGE))
            {
                tempValue = tempClass.DILevel;
            }
            else
            {
                foreach (SkillMod kvp in tempClass.levelBonuses)
                {
                    if (kvp.Equals(skill.name))
                    {
                        tempValue = kvp.value;
                    }
                }
            }

            return tempValue;
        }

        public static int getLevel()
        {
            return ((charac.totalTP - 500) / 100);
        }

        /// <summary>
        /// verifie si on peu depenser des PF pour cette skill
        /// </summary>
        /// <param name="skill/module">la skill/module ou les pf sont ajoutés</param>
        /// <param name="tpAdded">les tp a ajouter</param>
        /// <returns></returns>
        #region bool isValidSpendig(skill/module)
        public static bool isValidSpendig(BasicSkill skill, int tpAdded)
        {
            bool tempValid = false;

            switch (skill.type)
            {
                case TypeSkill.Combat:
                    if (tpCombat >= tpAdded)
                    {
                        tempValid = true;
                    }
                    if (skill.name.Equals(ATTACK) || skill.name.Equals(BLOCK) || skill.name.Equals(DODGE) && tempValid)
                    {
                        if (charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(ATTACK))].tP +
                            charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(BLOCK))].tP +
                            charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(DODGE))].tP <= charac.totalTP / 2)
                        {
                            if (charac.isAttBlockDiffValid)
                            {
                                tempValid = true;
                            }
                            else if (charac.isAttDodgeDiffValid)
                            {
                                tempValid = true;
                            }
                            else if (charac.isBlockAttDiffValid)
                            {
                                tempValid = true;
                            }
                            else if (charac.isDodgeAttDiffValid)
                            {
                                tempValid = true;
                            }
                            else if (charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(ATTACK))].tP == 0 &&
                                    (charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(BLOCK))].tP > 0 ||
                                    charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(DODGE))].tP > 0))
                            {
                                tempValid = true;
                            }
                            else if (charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(ATTACK))].tP > 0 &&
                                    charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(BLOCK))].tP == 0 &&
                                    charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(DODGE))].tP == 0)
                            {
                                tempValid = true;
                            }
                        }
                        else
                        {
                            tempValid = false;
                        }
                    }
                    break;
                case TypeSkill.Mystique:
                    if (tpMystic >= tpAdded)
                        tempValid = true;
                    if (skill.name.Equals(MAGIC_PRO))
                        if (charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(MAGIC_PRO))].tP
                            + tpAdded <= (charac.totalTP / 2 * getSkillCost(new BasicSkill(MYSTIC_LIMIT)) / 100) && tempValid)
                        {
                            tempValid = true;
                        }
                    break;
                case TypeSkill.Psionique:
                    if (tpPsychic >= tpAdded)
                        tempValid = true;
                    if (skill.name.Equals(PSY_PRO))
                        if ((charac.primarySkills[charac.primarySkills.IndexOf(new PrimarySkill(PSY_PRO))].tP
                            + tpAdded <= (charac.totalTP / 2 * getSkillCost(new BasicSkill(PSY_LIMIT)) / 100)) && tempValid)
                        {
                            tempValid = true;
                        }
                    break;
                case TypeSkill.Autre:
                    tempValid = true;
                    break;
            }

            return tempValid;
        }
        public static bool isValidSpendig(CombatModule module)
        {
            bool tempBool = false;

            switch (module.type)
            {
                case TypeSkill.Combat:
                    if (tpCombat >= module.cost)
                    {
                        tempBool = true;
                    }
                    break;
                case TypeSkill.Mystique:
                    if (tpMystic >= module.cost)
                    {
                        tempBool = true;
                    }
                    break;
                case TypeSkill.Psionique:
                    if (tpPsychic >= module.cost)
                    {
                        tempBool = true;
                    }
                    break;
                default:
                    tempBool = false;
                    break;
            }

            return tempBool;
        }
        #endregion
        #endregion

        public static Weapon getWeapon(string weapon)
        {
            Weapon tempWeapon = null;

            foreach (Weapon w in weaponList)
            {
                if (w.Equals(new Weapon(weapon)))
                    tempWeapon = w;
            }

            return tempWeapon;
        }

        public static TypicalModule getTypicalModule(string module)
        {
            TypicalModule tempModule = null;

            foreach (TypicalModule m in weaponModuleList)
            {
                if (m.Equals(new TypicalModule(module)))
                    tempModule = m;
            }

            return tempModule;
        }

        public static CombatModule getCombatModule(string module)
        {
            CombatModule tempModule = null;

            foreach (CombatModule m in combatModuleList)
            {
                if (m.Equals(new CombatModule(module)))
                    tempModule = m;
            }

            return tempModule;
        }

        public static Race getRace(string race)
        {
            Race tempRace = null;

            foreach (Race r in racesList)
            {
                if (r.Equals(race))
                {
                    tempRace = r;
                }
            }

            return tempRace;
        }

        public static CharacterClass getCharacterClass(string charClass)
        {
            CharacterClass tempClass = null;

            foreach (CharacterClass cc in classList)
            {
                if (cc.Equals(charClass))
                {
                    tempClass = cc;
                }
            }

            return tempClass;
        }

        #endregion

        #region SETTER_CHARACTER_INFO

        public static void saveCharacterInfo(Form saver, string charFileName)
        {
            xmlSerializeCharacter(charFileName);
            ((ICharacterSaved)saver).characterSaved(true);
        }

        public static void addAdvantageToCharac(AdvDisadv adv)
        {
            charac.advantage.Add(adv);
            charac.nbCreation -= adv.cost;
        }

        public static void addDisadvantageToCharac(AdvDisadv disadv)
        {
            charac.disadvantage.Add(disadv);
            charac.nbCreation -= disadv.cost;
            charac.nbDisadvantave += disadv.cost;
        }

        public static void setTPSpendings(TypeSkill type, int valueToSub)
        {
            switch (type)
            {
                case TypeSkill.Combat:
                    tpCombat -= valueToSub;
                    break;
                case TypeSkill.Mystique:
                    tpMystic -= valueToSub;
                    break;
                case TypeSkill.Psionique:
                    tpPsychic -= valueToSub;
                    break;
            }
        }

        public static void setTPAvailToSpend()
        {
            tpCombat = charac.totalTP * getSkillCost(new BasicSkill(MARTIAL_LIMIT)) / 100;
            tpMystic = charac.totalTP * getSkillCost(new BasicSkill(MYSTIC_LIMIT)) / 100;
            tpPsychic = charac.totalTP * getSkillCost(new BasicSkill(PSY_LIMIT)) / 100;
        }

        #endregion

        #region DATA_CONVERT

        /// <summary>
        /// prends une chaine de caractère et la convertie en int et verifie s'il est non nul
        /// </summary>
        /// <param name="value">la chaine de caractère a convertire</param>
        /// <param name="parent">la forme parent pour l'affichage des messages d'erreur</param>
        /// <returns>la chaine convertie</returns>
        public static int getIntFromString(String value, Form parent)
        {
            int tempValue = 0;

            if (value.Length != 0)
            {
                try
                {
                    tempValue = Convert.ToInt32(value);
                }
                catch (FormatException fe)
                {
                    MessageBox.Show(parent, "Entrer un nombre S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (OverflowException oe)
                {
                    MessageBox.Show(parent, "Entrer un nombre plus petit S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                if (tempValue <= 0)
                {
                    MessageBox.Show(parent, "Entrer un nombre plus grand que zéro S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            return tempValue;
        }

        /// <summary>
        /// prends une chaine de caractère et le convertie en int
        /// </summary>
        /// <param name="value">la chaine de caractère a convertire</param>
        /// <param name="parent">la forme parent pour l'affichage des messages d'erreur</param>
        /// <returns>la chaine convertie</returns>
        public static int getIntFromStringZero(String value, Form parent)
        {
            int tempValue = 0;

            if (value.Length != 0)
            {
                try
                {
                    tempValue = Convert.ToInt32(value);
                }
                catch (FormatException fe)
                {
                    MessageBox.Show(parent, "Entrer un nombre S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (OverflowException oe)
                {
                    MessageBox.Show(parent, "Entrer un nombre plus petit S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show(parent, "Entrer un nombre S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return tempValue;
        }

        /// <summary>
        /// prends une chaine de caractère et le convertie en float et verifie s'il est non nul
        /// </summary>
        /// <param name="value">la chaine de caractère a convertire</param>
        /// <param name="parent">la forme parent pour l'affichage des messages d'erreur</param>
        /// <returns>la chaine convertie</returns>
        public static float getFloatFromString(String value, Form parent)
        {
            float tempValue = 0;

            if (value.Length != 0)
            {
                try
                {
                    tempValue = Convert.ToSingle(value);
                }
                catch (FormatException fe)
                {
                    MessageBox.Show(parent, "Entrer un nombre S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (OverflowException oe)
                {
                    MessageBox.Show(parent, "Entrer un nombre plus petit S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            if (tempValue <= 0)
            {
                MessageBox.Show(parent, "Entrer un nombre plus grand que zéro S.V.P.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return tempValue;
        }

        /// <summary>
        /// Prends une chaine de caractere et retrourne le type de skill que cette chaine représente
        /// </summary>
        /// <param name="type">la chaine a analyser</param>
        /// <param name="parent">la forme parent pour l'affichage des messages d'erreur</param>
        /// <returns>le type de skill de la chaine</returns>
        public static TypeSkill getTypeSkillFromString(String type, Form parent)
        {
            TypeSkill tempType = TypeSkill.Erreur;

            foreach (string s in Settings.Default.AllSkillTypes)
            {
                if (s.Contains(type))
                {
                    tempType = (TypeSkill)Settings.Default.AllSkillTypes.IndexOf(s);
                }
            }

            return tempType;
        }

        /// <summary>
        /// Prends une chaine de caractere et retrourne la stat que cette chaine représente
        /// </summary>
        /// <param name="type">la chaine a analyser</param>
        /// <param name="parent">la forme parent pour l'affichage des messages d'erreur</param>
        /// <returns>la stat de la chaine</returns>
        public static Stats getStatFromString(String stat, Form parent)
        {
            Stats tempStat = Stats.Erreur;

            foreach (string s in Settings.Default.StatTypes)
            {
                if (s.Contains(stat))
                {
                    tempStat = (Stats)Settings.Default.StatTypes.IndexOf(s);
                }
            }

            return tempStat;
        }

        /// <summary>
        /// Prends une chaine de caractere et retrourne le skill set que cette chaine représente
        /// </summary>
        /// <param name="type">la chaine a analyser</param>
        /// <param name="parent">la forme parent pour l'affichage des messages d'erreur</param>
        /// <returns>le skill set de la chaine</returns>
        public static SkillSet getSkillSetFromString(String set, Form parent)
        {
            SkillSet tempSet = SkillSet.Erreur;

            foreach (string s in Settings.Default.SkillSet)
            {
                if (s.Contains(set))
                {
                    tempSet = (SkillSet)Settings.Default.SkillSet.IndexOf(s);
                }
            }

            return tempSet;
        }

        #endregion

        #region SERIALIZATION/DESERIALIZATION

        #region xmlSerializeCharacter
        /// <summary>
        /// Sauvegarde le personnge dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde le fichier</param>
        public static void xmlSerializeCharacter(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Character));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, charac);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec un personnge.
        /// </summary>
        ///<param name="filename">le fichier d'ou est lue le personnage</param>
        public static void xmlDeserializeCharacter(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Character));
            FileStream fs = new FileStream(filename, FileMode.Open);

            charac = (Character)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeXXXSkills
        /// <summary>
        /// Sauvegarde la liste de compétences autre dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les skills</param>
        public static void xmlSerializeOtherSkills(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<BasicSkill>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, basicSkillsList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de compétences autre.
        /// </summary>
        ///<param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeOtherSkills(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<BasicSkill>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            basicSkillsList = (List<BasicSkill>)serializer.Deserialize(fs);

            fs.Close();
        }

        /// <summary>
        /// Sauvegarde la liste de compétences primaire dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les skills</param>
        public static void xmlSerializePrimarySkills(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<PrimarySkill>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, primarySkillsList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de compétences primaire.
        /// </summary>
        ///<param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializePrimarySkills(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<PrimarySkill>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            primarySkillsList = (List<PrimarySkill>)serializer.Deserialize(fs);

            fs.Close();
        }

        /// <summary>
        /// Sauvegarde la liste de compétences secondaire dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les skills</param>
        public static void xmlSerializeSecSkills(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<SecondarySkill>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, secondarySkillsList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de compétences secondaire.
        /// </summary>
        ///<param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeSecSkills(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<SecondarySkill>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            secondarySkillsList = (List<SecondarySkill>)serializer.Deserialize(fs);

            fs.Close();
        }

        /// <summary>
        /// Sauvegarde la liste de compétences secondaire dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les skills</param>
        public static void xmlSerializeAllSkills()
        {
            xmlSerializeOtherSkills(Settings.Default.FilePath + Settings.Default.BasicSkills);
            xmlSerializePrimarySkills(Settings.Default.FilePath + Settings.Default.PrimarySkills);
            xmlSerializeSecSkills(Settings.Default.FilePath + Settings.Default.SecondarySkills);
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de compétences secondaire.
        /// </summary>
        ///<param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeAllSkills()
        {
            xmlDeserializeOtherSkills(Settings.Default.FilePath + Settings.Default.BasicSkills);
            xmlDeserializePrimarySkills(Settings.Default.FilePath + Settings.Default.PrimarySkills);
            xmlDeserializeSecSkills(Settings.Default.FilePath + Settings.Default.SecondarySkills);
        }
        #endregion

        #region xmlSerializeClasses
        /// <summary>
        /// Sauvegarde la liste des classes dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les classes</param>
        public static void xmlSerializeClasses(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<CharacterClass>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, classList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de classes.
        /// </summary>
        ///<param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeClasses(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<CharacterClass>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            classList = (List<CharacterClass>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeRaces
        /// <summary>
        /// Sauvegarde la liste des races dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les races</param>
        public static void xmlSerializeRaces(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Race>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, racesList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de races.
        /// </summary>
        /// <param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeRaces(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Race>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            racesList = (List<Race>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeAdvDisadv
        /// <summary>
        /// Sauvegarde la liste des races dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les races</param>
        public static void xmlSerializeAdvDisadv(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<AdvDisadv>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, advDisadvList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de races.
        /// </summary>
        /// <param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeAdvDisadv(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<AdvDisadv>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            advDisadvList = (List<AdvDisadv>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeWeapons
        /// <summary>
        /// Sauvegarde la liste des armes dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les armes</param>
        public static void xmlSerializeWeapons(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Weapon>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, weaponList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste d'armes.
        /// </summary>
        /// <param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeWeapons(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Weapon>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            weaponList = (List<Weapon>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeTypicalModule
        /// <summary>
        /// Sauvegarde la liste des modules typiques dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les modules typiques</param>
        public static void xmlSerializeTypicalModules(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<TypicalModule>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, weaponModuleList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de modules typiques.
        /// </summary>
        /// <param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeTypicalModules(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<TypicalModule>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            weaponModuleList = (List<TypicalModule>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeCombatModule
        /// <summary>
        /// Sauvegarde la liste des modules de combat dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les modules de combat</param>
        public static void xmlSerializeCombatModules(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<CombatModule>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, combatModuleList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste de modules de combat.
        /// </summary>
        /// <param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeCombatModules(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<CombatModule>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            combatModuleList = (List<CombatModule>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #region xmlSerializeMartialArts
        /// <summary>
        /// Sauvegarde la liste des arts martiaux dans un fichier XML.
        /// </summary>
        /// <param name="filename">le fichier ou sera sauvegarde les arts martiaux</param>
        public static void xmlSerializeMartialArts(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<MartialArts>));
            TextWriter writer = new StreamWriter(filename, false);

            serializer.Serialize(writer, martialArtsList);
            writer.Close();
        }

        /// <summary>
        /// Lecture d'un fichier xml avec une liste des arts martiaux.
        /// </summary>
        /// <param name="filename">le fichier d'ou est lue la liste</param>
        public static void xmlDeserializeMartialArts(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<MartialArts>));
            FileStream fs = new FileStream(filename, FileMode.Open);

            martialArtsList = (List<MartialArts>)serializer.Deserialize(fs);

            fs.Close();
        }
        #endregion

        #endregion

        #region COMMON_METHOD

        public static bool onCloseEvent(bool saved, Form thisForm, Form previousForm, FormClosingEventArgs formEvent)
        {
            if (formEvent.CloseReason != CloseReason.None)
            {
                if (!saved)
                {
                    DialogResult frmclose = MessageBox.Show("Voulez-vous quitter sans sauvegarder?", "Fermeture",
                                                                    MessageBoxButtons.YesNo,
                                                                    MessageBoxIcon.Question,
                                                                    MessageBoxDefaultButton.Button2);
                    if (frmclose == DialogResult.Yes)
                    {

                        if (thisForm.Owner.GetType() == new FormChoice().GetType())
                        {
                            thisForm.Owner.Show();
                        }
                        else
                        {
                            thisForm.Owner.Show(previousForm);
                        }
                        thisForm.Dispose();

                    }
                    else
                    {
                        return true;
                    }
                }
                else
                    if (thisForm.Owner.GetType() == new FormChoice().GetType())
                    {
                        thisForm.Owner.Show();
                    }
                    else
                    {
                        thisForm.Owner.Show(previousForm);
                    }
                thisForm.Dispose();
            }
            else
            {
                Utils.topForm.Show();
            }
            return false;
        }

        #endregion
    }
}
